/*
	pv uv ip
*/

/* global utils */
var LocalStorageUtil = {
        __enabled: true,
        isSupport: function() {
            return this.__enabled && window.localStorage ? true : false;
        },
        get: function(key) {
            return (key && this.isSupport()) ? window.localStorage.getItem(aeTracker.appId + "_" + key) : null;
        },
        set: function(key, value) {
            if (key && this.isSupport()) {
                window.localStorage.setItem(aeTracker.appId + "_" + key, value);
            }
        },
        remove: function(key) {
            if (key && this.isSupport()) {
                window.localStorage.removeItem(aeTracker.appId + "_" +key);
            }
        }, 
        disableCache: function() {
            this.__enabled = false;
        }
    };

var CookieUtil = {
    get: function(name) {
        var cookieName = encodeURIComponent(name) + "=",
            cookieStart = document.cookie.indexOf(cookieName),
            cookieValue = null;

        if (cookieStart > -1) {
            var cookieEnd = document.cookie.indexOf(";", cookieStart);
            if (cookieEnd == -1) {
                cookieEnd = document.cookie.length;
            }
            cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
        }

        return cookieValue;
    },

    /**
     * 
     */
    set: function(name, value, expires, path, domain, secure) {
        var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
        
        if (expires) {
            var expiresTime = new Date();
            expiresTime.setTime(expires);
            cookieText += "; expires=" + expiresTime.toGMTString();
        }

        if (path) {
            cookieText += "; path=" + path;
        }

        if (domain) {
            cookieText += "; domain=" + domain;
        }

        if (secure) {
            cookieText += "; secure";
        }

        document.cookie = cookieText;
    },

    unset: function(name, path, domain, secure) {
        this.set(name, "", new Date(0), path, domain, secure);
    }
};

(function() {
	var tracker = {
		clientConfig : {
			serverUrl: "http://localhost:8080/analytics/__ae.gif",
			sessionTimeout: 300,
            maxWaitTime: 3600,
            batchSize: 3,
            debugModel: true,
            pvEnabled: true,
            ver: "1",
            onerror: function() {this.utils.err("image error");},
            onload: function() {this.utils.err("image onload");}
		},
		twoYearTime: 63072000000,
		separateChar: '_',
		// if local storage is not support, we will send the event, error every time it appear.
		timedEvents: {},
        temp: null,
		appId: null,
		sessionAutoTimeout: true,
		batchSize: null,
		sessionTimeout: null,
		_ctx: "default",
		_batchStore: null,
		keys : {
			setCache: "setCache",
            pvEnabled: "pvEnabled",
            tagEnabled: "tagEnabled",
            cpEnabled: "cpEnabled",
            onerror: "onerror",
            onload: "onload",
            time: "ts",
            firstVisitTime: "firstVisitTime",
            preVisitTime: "preVisitTime",
            timedEvents: "timedEvents",
            sessionTimeout: "sessionTimeout",
            batchSize: "batchSize",
            serverUrl:"serverUrl",
            localCachedRequest: "localCachedRequest",
            currentSize: "currentSize",
            maxWaitTime: "maxWaitTime",
            websitePlatform: "website",

            // send to server
            userAgent: "u_ag",
            launch: "e_l",
            pageView: "e_pv",
            pageClick: "e_pc",
            userId: "u",
            url: "url",
            referrer: "ref",
            title: "tt",
            hash: "ha",
            host: "ht",
            search:"sc",
            javaEnabled: "je",
            colorDepth: "cd",
            cookieEnabled: "ce",
            flashVersion: "flav",

            // use in both
            category: "c",
            duration: "du",
            action: "ac",
            kv: "kv",
            cid: "cid",
            oldCid: "old_cid",

            sid: "sid",
            location: "location",
            events: "e",
            userInfo: "uif",
            error: "er",
            errors: "er",
            latitude: "lat",
            longitude: "lng",
            locationAccuracy: "la",
            clientInfo: "cif",
            sessionInfo: "sif",
            appId: "aid",
            appVersion: "av",
            sdkType: "sdk",
            platform: "pl",
            body: "b",
            newCustom: "nu",
            resolution: "re",
            terminate: "e_t",
            eventKey: "eventKey",
            eventValue: "eventValue",
            type: "t",
            orderId: "oid",
            orderName: "on",
            currencyAmount: "cua",
            paymentType: "pt",
            currencyType: "cut",
            chargeRequestEvent: "e_cr",
            merchant: "me",
            Default: "default",
            refundEvent: "e_r",
            chargeSuccessEvent: "e_cs",
            reason: "r",
            purchaseEvent: "e_p",
            item: "i",
            number: "num",
            tag: "tg",
            tagViewedEvent: "e_tv",
            version: "ver",
            campaignId: "cpi",
            cpViewEvent: "cpm",
            cpEngageEvent: "cpe",
            cpConvertEvent: "cpc",
            cpConvertValue: "cpv"
		},

		clientInfo: {},
        sessionInfo: {},
        userInfo: {},

        getEventKeys: function() {
                return [
            this.keys.events,
            this.keys.errors,
            this.keys.pageView,
            this.keys.pageClick, 
            this.keys.chargeRequestEvent, 
            this.keys.chargeSuccessEvent,
            this.keys.refundEvent,
            this.keys.purchaseEvent,
            this.keys.cpViewEvent,
            this.keys.cpEngageEvent,
            this.keys.cpConvertEvent,
            this.keys.tagViewedEvent
            ];
        },

        setCid: function(cid) {
        	this.utils.log("set new cid: " + cid);
            var time = new Date().getTime();
            if (cid && cid.length == 32) {
            	CookieUtil.set(this.keys.cid, cid, time + this.twoYearTime, "/"); 
            } else {
            	return this.utils.err("cid has wrong format");
            }
        },

        setSid: function(sid) {
            if (sid) {
                var time = new Date().getTime();
                this.sessionAutoTimeout = false;
                CookieUtil.set(this.keys.sid, sid, time + this.twoYearTime, "/");
            }
        },

        /**
         * If user login your application, you need to call this API to set the user id.
         */
        setUserId: function(userId) {
        	this.utils.log("setUserId is called with userId: " + userId);
        	if (userId) {
        		if (LocalStorageUtil.isSupport()) {
        			LocalStorageUtil.set(this.keys.userId, userId);
        		}
        		this.sessionInfo[this.keys.userId] = userId;
        	}
        },

        /**
         * When you call endSession, if user goes back to the application in 600 seconds,
         * this session should not be treated as a new session, so you can set the interval to 600.
         * When the session is timeout, will start new Session and trigger 'launch' event.
         */
        setSessionTimeout: function(interval) {
            this.utils.log("setSessionTimeout is called");
            if (interval) {
                this.clientConfig[this.keys.sessionTimeout] = interval;
                if (LocalStorageUtil.isSupport()) {
                    LocalStorageUtil.set(this.keys.sessionTimeout, interval);
                }
            }
        },

        isSessionTimeout: function() {
            var time = new Date().getTime();
            var preTime = CookieUtil.get(this.keys.preVisitTime);
            if (preTime) {
                return time - preTime > this.clientConfig[this.keys.sessionTimeout] * 1000;
            }
            return true;
        },

        disablePageView: function() {
            this.utils.log("disablePageView is called");
            this.clientConfig[this.keys.pvEnabled] = false;
        },

        /**
         * if support localStorage we will cache the data first, and send them by batch,
         * use setBatchSize to control the size, default is 100
         */
        setBatchSize: function(newSize) {
            this.utils.log("setBatchSize is called");
            if (newSize && (newSize >= 1) && LocalStorageUtil.isSupport()) {
                var currentDataSize = Number(LocalStorageUtil.get(this.keys.currentSize));
                if (currentDataSize >= newSize) {
                    this.sendDataToServer();
                }
                this.clientConfig[this.keys.batchSize] = newSize;
                LocalStorageUtil.set(this.keys.batchSize, newSize);
            }
        },

        init: function() {
        	if (LocalStorageUtil.isSupport()) {
        		var sessionTimeout = LocalStorageUtil.get(this.keys.sessionTimeout);
        		var batchSize = LocalStorageUtil.get(this.keys.batchSize);
    		  	if (sessionTimeout) {
                    this.clientConfig[this.keys.sessionTimeout] = sessionTimeout;
                } else {
                    LocalStorageUtil.set(this.keys.sessionTimeout, this.clientConfig[this.keys.sessionTimeout]);
                }
                if (batchSize) {
                    this.clientConfig[this.keys.batchSize] = batchSize;
                } else {
                    LocalStorageUtil.set(this.keys.batchSize, this.clientConfig.batchSize);
                }

                if (this.sessionInfo[this.keys.userId]) {
                    LocalStorageUtil.set(this.keys.userId, this.sessionInfo[this.keys.userId]); 
                    delete this.sessionInfo[this.keys.userId];
                }
        	}
        },

        startSession: function(appId, appVersion, platform) {
        	this.utils.log("startSession is called with appId: " + appId + ",appVersion: " + appVersion + ",platform: " + platform);
        	if (LocalStorageUtil.isSupport()) {
        		appId && (this.appId = appId) && (LocalStorageUtil.set(this.keys.appId, appId));
        		appVersion && (LocalStorageUtil.set(this.keys.appVersion, appVersion));
        		platform && (LocalStorageUtil.set(this.keys.platform, platform));
        	} else {
        		appId && (this.clientInfo[this.keys.appId] = appId);
        		appVersion && (this.clientInfo[this.keys.appVersion] = appVersion);
        		platform && (this.clientInfo[this.keys.platform] = platform);
        	}

        	this.init();
        	// 1. check whether exsit session info in the localStorage;
        	if (CookieUtil.get(this.keys.sid)) {
        		// 2. check whether it's timeout;
        		if (this.sessionAutoTimeout && this.isSessionTimeout()) {
        			// 3. session timeout, create new session, trigger 'launch' event;
        			this.utils.log("session timeout, send last data and create new session");
        			this.createNewSession(true);
        		} else {
        			// 3. resume the last session
        			this.utils.log("resume the last session");
        			var time = new Date().getTime();
        			this.updatePreVisitTime(time);
        		}
        	} else {
        		// 2. session timeout, create new session
        		this.utils.log("create new session");
        		this.createNewSession();
        	}

        	this.events.trackingWebsite();
        },
        /**
		 * @param isTimeout whether is it timeout
		 */        
        createNewSession: function(isTimeout) {
        	var body = {};
        	if (isTimeout) {
        		var terminate = {};
        		terminate[this.keys.sid] = CookieUtil.get(this.keys.sid);
        		var endTimeOfLastSession = CookieUtil.get(this.keys.preVisitTime);
        		terminate[this.keys.time] = parseInt(endTimeOfLastSession);
        		// last visit time, it contains per page visit time
        		terminate[this.keys.duration] = endTimeOfLastSession - CookieUtil.get(this.keys.firstVisitTime);
        		var terminates = [];
        		terminates.push(terminate);
        		body[this.keys.terminate] = terminates;
        	}

        	var launch = {};
        	var time = new Date().getTime();
        	// if cid does't exist, will generate it
        	if (! CookieUtil.get(this.keys.cid)) {
        		var cid = this.utils.generateId();
        		CookieUtil.set(this.keys.cid, cid, time + this.twoYearTime, "/");
        		this.clientInfo[this.keys.newCustom] = 1;
        		launch[this.keys.newCustom] = 1; // probably a new custom
        	}

        	if (this.clientInfo[this.keys.newCustom]) {
        		delete this.clientInfo[this.keys.newCustom]; // initial the key
        	}

        	var sid = this.utils.generateId();
        	CookieUtil.set(this.keys.sid, sid, time + this.twoYearTime, "/");
        	this.updatePreVisitTime(time);
        	CookieUtil.set(this.keys.firstVisitTime, time, time + this.twoYearTime, "/");
        	LocalStorageUtil.set(this.keys.currentSize, 0);

        	launch[this.keys.sid] = sid;
        	launch[this.keys.time] = time;
        	launch = this.fillUserInfo(launch);
        	var launchs = [];
        	launchs.push(launch);
        	body[this.keys.launch] = launchs;

        	var data = {};
        	data[this.keys.body] = body;

        	this.sendDataToServer(data);
        },

        fetchUserInfo: function() {
        	var userInfo = {};
        	if (LocalStorageUtil.isSupport()) {
        		var userInfoStr = LocalStorageUtil.get(this.keys.userInfo);
        		userInfoStr && (userInfo = JSON.parse(userInfoStr));
        	} else {
        		// deep copy here, not refer
        		userInfo = JSON.parse(JSON.stringify(this.userInfo));
        	}
        	return userInfo;
        },

        fillUserInfo: function(eventData) {
        	var storeUserInfo = this.fetchUserInfo();
        	if (storeUserInfo) {
        		if (JSON.stringify(storeUserInfo) !== "{}") {
					eventData[this.keys.userInfo] = storeUserInfo;
        		}
        	}
        },

        getUserId: function() {
            var userId;
            if (LocalStorageUtil.isSupport()) {
                userId = LocalStorageUtil.get(this.keys.userId);
            } else {
                userId = this.sessionInfo[this.keys.userId];
            }
            return userId;
        },

        setUserInfo: function(userInfo) {
        	var storeUserInfo = this.fetchUserInfo();
        	if (userInfo) {
        		for (var key in userInfo) {
        			storeUserInfo[key] = userInfo[key];
        		}
        	} else {
        		return this.utils.err("userInfo must be a Object, can't be null");
        	}

        	this.saveUserInfo(storeUserInfo);
        },

        saveUserInfo: function(storeUserInfo) {
        	if (LocalStorageUtil.isSupport()) {
                var userInfo = JSON.stringify(storeUserInfo);
                LocalStorageUtil.set(this.keys.userInfo, userInfo);
            } else {
                this.userInfo = storeUserInfo;
            }
        },

		sendDataToServer: function(extraData) {

			this.utils.log("extraData: " + extraData);

			this.preSendData();

			var data = {};
			if (extraData) {
				data = extraData;
			}
			data[this.keys.version] = this.clientConfig[this.keys.version];
			var clientInfo = this.getClientInfo();
			data[this.keys.clientInfo] = clientInfo;
			var sessionInfo = this.getSessionInfo();
			data[this.keys.sessionInfo] = sessionInfo;
			var body = {};
			if (extraData && extraData[this.keys.body]) {
                body = extraData[this.keys.body];
            }

            // iterator all event
            var eventKeys = this.getEventKeys();
            if (LocalStorageUtil.isSupport()) {
            	for (var i = 0; i < eventKeys.length; i++) {
            		var cache = LocalStorageUtil.get(eventKeys[i]);
            		if (cache) {
            			body[eventKeys[i]] = body[eventKeys[i]]? body[eventKeys[i]].concat(JSON.parse(cache)) : JSON.parse(cache);
            		}
            	}
            } else {
				if (this.temp) {
                    body[this.temp[this.keys.eventKey]] = [this.temp[this.keys.eventValue]];
                }
            }

            if (this.utils.isEmpty(body)) {
            	return;
            }

            data.[this.keys.body] = body;

            this.utils.log(JSON.stringify(data));
            var dataStr = encodeURIComponent(JSON.stringify(data));
            this.utils.log("send data to server: " + dataStr);
            this.sendRequest(dataStr);
            this.reset();
		},

		sendRequest: function(dataStr) {
			var that = this;
			var img = new Image(1, 1);
			img.onerror = function() {
				that.savaInLocal(dataStr);
				that.clientConfig[that.keys.onerror]&&that.clientConfig[that.keys.onerror]();
			};
			img.onload = function() {
				that.clientConfig[that.keys.onload]&&that.clientConfig[that.keys.onload]();
			}

			img.src = that.clientConfig[that.keys.serverUrl] + "?d=" + dataStr+"&r="+new Date().getTime();
		},

		saveInLocal: function(dataStr) {
            if (LocalStorageUtil.isSupport()) {
                var localRequestsStr = LocalStorageUtil.get(this.keys.localCachedRequest);
            
                var requests = [];
                if (localRequestsStr) {
                    requests = requests.concat(JSON.parse(localRequestsStr));
                }   
                requests.push(dataStr);
                LocalStorageUtil.set(this.keys.localCachedRequest, JSON.stringify(requests));
            }
        },

        preSendData: function() {
            if (LocalStorageUtil.isSupport()) {
                var localRequestsStr = LocalStorageUtil.get(this.keys.localCachedRequest);
                LocalStorageUtil.remove(this.keys.localCachedRequest);
                var requests = [];
                if (localRequestsStr) {
                    requests = requests.concat(JSON.parse(localRequestsStr));
                }
                var size = requests.length;
                for (var i = size; i > 0; i-- ) {
                    var dataStr = requests[i-1];
                    this.sendRequest(dataStr);
                }
            }
        },

		getClientInfo: function() {
			var clientInfo = {};
			var appId, appVersion, platform;
			if (LocalStorageUtil.isSupport()) {
                appId = LocalStorageUtil.get(this.keys.appId);
                appVersion = LocalStorageUtil.get(this.keys.appVersion);
                platform = LocalStorageUtil.get(this.keys.platform);
            } else {
                appId = this.clientInfo[this.keys.appId];
                appVersion = this.clientInfo[this.keys.appVersion];
                platform = this.clientInfo[this.keys.platform];
            }

            appId && (clientInfo[this.keys.appId] = appId);
            appVersion && (clientInfo[this.keys.appVersion] = appVersion);
            platform && (clientInfo[this.keys.platform] = platform);
            clientInfo[this.keys.sdkType] = "js";
            clientInfo[this.keys.resolution] = screen.width + "*" + screen.height;
            var cid = CookieUtil.get(this.keys.cid);
            clientInfo[this.keys.cid] = cid;
            var oldCid = this.clientInfo[this.keys.oldCid];
            if (oldCid) {
            	clientInfo[this.keys.oldCid] = oldCid;
            }
            var userAgent = navigator.userAgent;
            userAgent && (clientInfo[this.keys.userAgent] = userAgent);
            //if platform is website add color & java_enable & cookie_enable & flash_version
            if (platform && platform === this.keys.websitePlatform) {
                clientInfo[this.keys.colorDepth] = window.screen.colorDepth;
                clientInfo[this.keys.javaEnabled] = navigator.javaEnabled() ? 0 : 1;
                clientInfo[this.keys.cookieEnabled] = navigator.cookieEnabled ? 0 : 1;
                clientInfo[this.keys.flashVersion] = this.getFlashVersion();
            }
            return clientInfo;
		},

		getSessionInfo: function(){
            var singleSessionInfo = {};
            var userId, latitude, longitude, locationAccuracy;
            if (LocalStorageUtil.isSupport()) {
                userId = LocalStorageUtil.get(this.keys.userId);
                latitude = LocalStorageUtil.get(this.keys.latitude);
                longitude = LocalStorageUtil.get(this.keys.longitude);
                locationAccuracy = LocalStorageUtil.get(this.keys.locationAccuracy);
            } else {
                userId = this.sessionInfo[this.keys.userId];
                latitude = this.sessionInfo[this.keys.latitude];
                longitude = this.sessionInfo[this.keys.longitude];
                locationAccuracy = this.sessionInfo[this.keys.locationAccuracy];
            }
            
            userId && (singleSessionInfo[this.keys.userId] = userId);
            latitude && (singleSessionInfo[this.keys.latitude] = latitude);
            longitude && (singleSessionInfo[this.keys.longitude] = longitude);
            locationAccuracy && (singleSessionInfo[this.keys.locationAccuracy] = locationAccuracy);
            var sessionInfo = {};
            sessionInfo[CookieUtil.get(this.keys.sid)] = singleSessionInfo;
            return sessionInfo;
        },

        /**
         * set currentSize in localStorage to 0,
         * set events to null
         */
        reset: function() {
        	LocalStorageUtil.set(this.keys.currentSize, 0);
        	var eventKeys = this.getEventKeys();
        	if (LocalStorageUtil.isSupport()) {
        		for (var i = 0; i < eventKeys.length; i++) {
                    LocalStorageUtil.remove(eventKeys[i]);
                } 
        	}
        },

        /**
         * FIXME: how to judge a new custom, this will affect the UV statistic	(see startSession())
         * check whether need start a new session when call API, for example, one user stay in
         * one page(may read book or watch film) for a long time, and the time is longer than "sessionTimeout",
         * if the time is less than "maxWaitTime" we did not regard it as timeout. But if the time is longer than
         * "maxWaitTime" we think the user was left before, so we start a new session.
         * @return true if the API is able to call. otherwise return false(may the user did not call the startSession API)
         */
        preCallApi: function() {
        	var time = new Date().getTime();
        	var preTime = CookieUtil.get(this.keys.preVisitTime);
        	var appId = LocalStorageUtil.get(this.keys.appId) || this.clientInfo[this.keys.appId];
        	// if have no appId or preTime, we think the client have not call startSession API
        	if (preTime && appId) {
        		var isNeedStart = (time - preTime) > this.clientConfig[this.keys.maxWaitTime] * 1000;

        		if (isNeedStart) {
        			this.startSession();
        		} else {
        			 this.updatePreVisitTime(time);
        		}

        		return true;
        	} else {
        		return this.utils.err("you have not call startSession API");
        	}
        },

        events: {
        	trackingWebsite: function() {
        		var pvEnabled = this.clientConfig[this.keys.pvEnabled];
        		if (pvEnabled) {
                    this.events.onPageView();
                }
        	},

        	onPageView: function() {
        		if (! this.preCallApi()) {
        			return;
        		}

        		var time = new Date().getTime();
        		var sid = CookieUtil.get(this.keys.sid);
        		var userId = this.getUserId();

        		var pageViewEvent = {};
        		pageViewEvent[this.keys.sid] = sid;
        		if(userId){
                	pageViewEvent[this.keys.userId] = userId;
                }
                pageViewEvent[this.keys.time] = time;

                var __loc = window.location;
                if (window.document.referrer && window.document.referrer !== "") {
                	pageViewEvent[this.keys.referrer] = this.getReferrer();
                }
                if (window.document.title && window.document.title !== "") {
                	pageViewEvent[this.keys.title] = encodeURIComponent(window.document.title);
                }
                pageViewEvent[this.keys.url] = __loc.protocol + '//' + __loc.host + __loc.pathname;

                if(__loc.search){
                    pageViewEvent[this.keys.search] = __loc.search;
                }

                if (__loc.hash && __loc.hash !== "") {
                    pageViewEvent[this.keys.hash] = __loc.hash;
                }

                this.dispatch(this.keys.pageView, pageViewEvent);
                this.updatePreVisitTime(time);
        	}
        },

        dispatch: function(eventKey, eventData) {
        	var eventData = eventKey === this.keys.errors ? eventData : this.fillUserInfo(eventData);
        	if (this._ctx === "default") {
        		this._handleDefaultCtx(eventKey, eventData);
        	} else if (this._ctx === "batch") {
        		this._handleBatchCtx(eventKey, eventData);
        	}
        },

        _handleDefaultCtx: function(eventKey, eventData) {
        	if (LocalStorageUtil.isSupport()) {
        		var oldEventsStr = LocalStorageUtil.get(eventKey);
		    	var events = oldEventsStr ? JSON.parse(oldEventsStr) : [];

		    	events.push(eventData);
		    	var eventsStr = JSON.stringify(events);
		    	LocalStorageUtil.set(eventKey, eventsStr);

		    	var currentSize = Number(LocalStorageUtil.get(this.keys.currentSize));
		    	var batchSize = Number(LocalStorageUtil.get(this.keys.batchSize));
		    	if (currentSize + 1 < batchSize) {
		    		LocalStorageUtil.set(this.keys.currentSize, currentSize + 1);
		    	} else {
		    		this.sendDataToServer();
		    		return;
		    	}
        	} else {
        		this.temp = {};
                this.temp[this.keys.eventKey] = eventKey;
                this.temp[this.keys.eventValue] = eventData;
                this.sendDataToServer();
        	}
        	
        },

        _handleBatchCtx: function(eventKey, eventData) {
        	if (! this._batchStore) {
        		this._batchStore = {};
        	}

        	//if _batch is running, just save data into this._batchStore
        	var events = this._batchStore[eventKey]? this._batchStore[eventKey] : [];
        	events.push(eventData);
        	this._batchStore[eventKey] = events;
        },

        _completeBatch: function() {
            //recycle the this._batchStore.
            if (this._batchStore) {
                var reqData = {};
                reqData[this.keys.body] = this._batchStore;
                this.sendDataToServer(reqData);
            }
            this._batchStore = null;
            this._ctx = "default";
        },

        utils : {
        	generateId : function() {
				var id = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
				    var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
				    return v.toString(16);
				});
				return id;
			},

			isNumber : function(param) {
                return (typeof param === "number");
            },

            isEmpty: function(obj) {
                if (obj === null) {
                    return true;
                }
                if (obj.length && obj.length > 0) {
                    return false;
                }
                if (obj.length && obj.length ==0) {
                    return true;
                }
                var size = 0;
                for (var key in obj) {
                    size = size + 1;
                }
                return size === 0;
            },

            concatKeys: function (category, action, label, value) {
                var key = "";
                category && (key = key + category + this.separateChar);
                action && (key = key + action + this.separateChar);
                label && (key = key + label + this.separateChar);
                value && (key = key + value + this.separateChar);
                return key;
            },

            log: function(message){
                if (this.clientConfig.debugModel) {
                    console.log(message);
                }
            },

            err: function(message) {
            	alert(message);
            	return;
            }
        }
	}
})();